<?php

namespace  asyncService\processHandles;

use asyncService\lib\ProcessHandle;
use asyncService\lib\log;
use asyncService\mainService;
use asyncService\message\messageFactory;


class parentHandle extends ProcessHandle {

    protected $message;

    protected $stop_key ;

    protected $log ;

    protected $_step_number = 20;

    protected $_max_number = 0;
    protected $_number = 0;

    /**
     * 默认消息读取间隔
     * @var int
     */
    protected $_sleep_mtime = 1000;

    function __construct($worker, $mainService)
    {
        parent::__construct($worker, $mainService);

        $this->log = log::getInstance("parentHandle");
    }

    public function handle(){

        $this->message  = messageFactory::Produce();

        $this->stop_key = $this->mainService->getServiceKey();

        $this->_max_number = $this->_step_number * count($this->mainService->services);

        parent::handle();
    }

	function callback() {

	    //监听信息
        $this->listenMessage();

        $this->processNextSleepTime();

        if($ret = $this->message->hasSignal($this->stop_key)){
            $this->run = false;

            $this->stopSubProcess();

            log::getInstance()->info("parent send stop message!");

            $this->message->removeSignal($this->stop_key);
        }

        log::getInstance()->debug("in parent next !");

        if($this->_sleep_mtime>200){
            usleep($this->_sleep_mtime*1000);
        }
	}

	function listenMessage(){

        $this->log->debug("listen message bgin!");
        $this->_number = 0;

		for( $i=1; $i<=$this->_step_number; $i++ ){
			foreach($this->mainService->services as $place => $service){
                $this->log->debug("listen service message bgin!");
				if($message = $service->pop()){
					$this->_number++;
				    $this->worker->push(json_encode([mainService::EVENT_DATA,['p'=>$place,$message]]));
	 			}
                $this->log->debug("listen service message end!");
			}
		}

        $this->log->debug("listen message end!");
    }

	function stopSubProcess(){
        $process = $this->mainService->process;

        foreach($process->child_works_pids as $pid){
            log::getInstance()->info("stop sub process!");
            $this->worker->push(json_encode([mainService::EVENT_STOP,$pid]));
        }
    }

    function processNextSleepTime(){
	    $leisure_number = $this->_max_number - $this->_number;

	    //休息时间变长
	    if($leisure_number > ($this->_max_number/2) ){
            $this->_sleep_mtime = ceil($this->_sleep_mtime*(1+$leisure_number/$this->_max_number));
        }else{
	        if($leisure_number>0){
                $this->_sleep_mtime = ceil($this->_sleep_mtime*(1-$leisure_number/$this->_max_number));
            }else{
                $this->_sleep_mtime = ceil($this->_sleep_mtime*0.5);
            }
        }

        if($this->_sleep_mtime<200){
	        $this->_sleep_mtime = 200;
        }elseif($this->_sleep_mtime > 3000){
            $this->_sleep_mtime = 3000;
        }
	}
}